package com.lxh.miniapp.config;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.*;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import cn.binarywang.wx.miniapp.message.WxMaMessageHandler;
import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.Data;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * created by lanxinghua@2dfire.com on 2020/2/23
 */
@Configuration
@Data
@EnableConfigurationProperties(WxMiniAppProperties.class)
public class WxMiniAppConfiguration {
    private static final Logger logger = LoggerFactory.getLogger(WxMiniAppConfiguration.class);
    private WxMiniAppProperties miniAppProperties;

    private static Map<String/*appid*/, WxMaMessageRouter> routers = Maps.newHashMap();
    private static Map<String/*appid*/, WxMaService> maServices = Maps.newHashMap();

    public WxMiniAppConfiguration(WxMiniAppProperties miniAppProperties) {
        this.miniAppProperties = miniAppProperties;
    }

    public static WxMaService getMaService(String appid) {
        WxMaService wxService = maServices.get(appid);
        if (wxService == null) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        }
        return wxService;
    }

    public static WxMaMessageRouter getRouter(String appid) {
        return routers.get(appid);
    }


    /**
     * 优先进行初始化
     */
    @PostConstruct
    public void init(){
        // 1.获取到所有小程序的配置
        List<WxMiniAppProperties.Config> configs = miniAppProperties.getConfigs();
        if (configs == null) {
            throw new RuntimeException("请添加下相关配置，注意别配错了！");
        }

        // 2.初始化maService和消息路由
        maServices = configs.stream().map(e -> {
            WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
            config.setAppid(e.getAppid());
            config.setSecret(e.getSecret());
            config.setToken(e.getToken());
            config.setAesKey(e.getAesKey());
            config.setMsgDataFormat(e.getMsgDataFormat());

            WxMaService maService = new WxMaServiceImpl();
            maService.setWxMaConfig(config);
            routers.put(e.getAppid(), this.newRouter(maService));
            return maService;
        }).collect(Collectors.toMap(a-> a.getWxMaConfig().getAppid(), a-> a));
    }

    /**
     * 新建路由
     * @param maService
     * @return
     */
    private WxMaMessageRouter newRouter(WxMaService maService){
        final WxMaMessageRouter router = new WxMaMessageRouter(maService);
        // 配置路由规则
        router.rule().handler(LogHandler).next()
                .rule().async(false).msgType(WxConsts.KefuMsgType.TEXT).handler(textHandler).end();
        return router;
    }


    private final WxMaMessageHandler LogHandler = (message, context, service, sessionManager) -> {
        logger.info("【消息日志】：" + message.toString());
        return null;
    };

    private final WxMaMessageHandler textHandler = (message, context, service, sessionManager) -> {
        logger.info("textHandler：" + message.toString());
        String msg = message.getContent();
        switch (msg){
            case "图片":{
                sendPic(service, message);
                break;
            }
            case "模板":{
                sendTemplate(service, message);
                break;
            }
            case "订阅":{
                sendSubscribeMsg(service, message);
                break;
            }
            case "二维码":{
                sendQrCode(service, message);
                 break;
            }
            default:{
                sendText(service, message);
                break;
            }
        }
        return null;
    };

    private void sendText(WxMaService service, WxMaMessage message){
        try {
            service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息")
                    .toUser(message.getFromUser()).build());
        }catch (Exception e){
            logger.error(e.getMessage());
        }
    }

    private void sendPic(WxMaService service, WxMaMessage message){
        try {
            WxMediaUploadResult uploadResult = service.getMediaService()
                    .uploadMedia("image", "jpg", ClassLoader.getSystemResourceAsStream("lxh.jpg"));
            service.getMsgService().sendKefuMsg(
                    WxMaKefuMessage
                            .newImageBuilder()
                            .mediaId(uploadResult.getMediaId())
                            .toUser(message.getFromUser())
                            .build());
        } catch (WxErrorException e) {
            logger.error(e.getMessage());
        }
    }


    // 由于“模板消息”将下线，已不再支持添加模板，请尽快接入“订阅消息”。
    private void sendTemplate(WxMaService service, WxMaMessage message){
        try {
            service.getMsgService().sendTemplateMsg(WxMaTemplateMessage.builder()
                    .templateId("2KwZNrdSs78NToB2CBzNKMfwoDN4fAggC7jJAweA4hM")
                    .formId("自己替换可用的formid")
                    .data(Lists.newArrayList(
                            new WxMaTemplateData("keyword1", "模板替换值。。。", "#173177")))
                    .toUser(message.getFromUser())
                    .build());
        }catch (Exception e){
            logger.error(e.getMessage());
        }
    }


    private void sendSubscribeMsg(WxMaService service, WxMaMessage message){
        try {
            service.getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()
                    .templateId("2KwZNrdSs78NToB2CBzNKMfwoDN4fAggC7jJAweA4hM")
                    .data(Lists.newArrayList(
                            new WxMaSubscribeData("thing1", "一起学习呀", "#173177"),
                            new WxMaSubscribeData("thing2", "今晚一起去图书馆学习啊", "#173177")
                            ))
                    .toUser(message.getFromUser())
                    .build());
        }catch (Exception e){
            logger.error(e.getMessage());
        }
    }

    private void sendQrCode(WxMaService service, WxMaMessage message){
        try {
            final File file = service.getQrcodeService().createQrcode("qrCode", 430);
            WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia("image", file);
            service.getMsgService().sendKefuMsg(
                    WxMaKefuMessage
                            .newImageBuilder()
                            .mediaId(uploadResult.getMediaId())
                            .toUser(message.getFromUser())
                            .build());
        } catch (WxErrorException e) {
            logger.error(e.getMessage());
        }
    }
}
